package com.jt.permission.controller;

import com.jt.base.utils.Constant;
import com.jt.base.utils.PageUtil;
import com.jt.base.utils.R;
import com.jt.permission.model.Menu;
import com.jt.permission.service.MenuService;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author longheping
 * @date 2018/7/31 10:11
 */
@RestController
@RequestMapping("admin/sys/menu")
@Validated
public class MenuController {

    @Resource
    private MenuService sysMenuService;

    @RequestMapping("/search")
    public R search(
            @Valid @Min(value = 0, message = "页码不能小于0") int page,
            @Valid @Max(value = 1000, message = "请求数量最大不能超过1000") int limit,
            @RequestParam(value = "menuId", required = false) Long menuId,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "status", required = false) Integer status,
            @RequestParam(value = "type", required = false) Integer type,
            @RequestParam(value = "parentId", required = false) Long parentId
    ) {
        Example example = new Example(Menu.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(name)) {
            criteria.andLike("name", "%" + name + "%");
        }
        if (menuId != null) {
            criteria.andEqualTo("menuId", menuId);
        }
        if (status != null) {
            criteria.andEqualTo("status", status);
        }
        if (type != null) {
            criteria.andEqualTo("type", type);
        }else {
            criteria.andIn("type", Lists.newArrayList(Constant.MenuType.MENU.getValue(), Constant.MenuType.CATALOG.getValue()));
        }
        if (parentId != null) {
            criteria.andEqualTo("parentId", parentId);
        }
        List<Menu> list = sysMenuService.selectListByExample(example, page, limit);
        return PageUtil.wrap(new PageInfo<>(list), R.ok());
    }

    /**
     * 获取所有菜单附带角色信息
     */
    @RequestMapping("/getMenuWithRoleInfo")
    public R getMenuWithRoleInfo(@RequestParam(required = false, defaultValue = "0") Long roleId) {
        List<Menu> menuList = sysMenuService.selectAll();//获取所有菜单
        if (roleId > 0) {
            List<Menu> menus = sysMenuService.queryAllMenus(Lists.newArrayList(roleId));//获取角色拥有的菜单
            menuList.stream().forEach(menu ->                //遍历两个list，选出角色拥有的菜单
                    menus.stream().forEach(m -> {
                        if (m.getMenuId().equals(menu.getMenuId())) {
                            menu.setHasOwn(1);
                        }
                    })
            );
        }
        return PageUtil.wrap(new PageInfo<>(menuList), R.ok());
    }


    /**
     * 保存用户
     */
    @RequestMapping("/save")
    public R save(@RequestBody Menu sysMenu) {
        boolean isNew = true;
        if (StringUtils.isEmpty(sysMenu.getIcon())) {
            sysMenu.setIcon("&#xe634;");
        }
        if (sysMenu.getMenuId() != null) {
            Menu dbSysMenu = sysMenuService.selectByKey(sysMenu.getMenuId());
            if (dbSysMenu != null) {
                isNew = false;
                sysMenuService.updateNotNull(sysMenu);
            }
        }
        if (isNew) {
            sysMenu.setStatus(1);
            sysMenu.setCreateTime(new Date());
            sysMenuService.insert(sysMenu);
        }
        /** 如果是菜单，自动添加按钮权限 * */
        if (sysMenu.getType().intValue() == Constant.MenuType.MENU.getValue()) {
           if(StringUtils.isEmpty(sysMenu.getPerms())){
               Example example = new Example(Menu.class);
               example.createCriteria()
                               .andEqualTo("parentId", sysMenu.getMenuId())
               .andEqualTo("type",Constant.MenuType.BUTTON.getValue());
               sysMenuService.deleteByExample(example);
           }else {
               String[] ss = sysMenu.getUrl().split("/");
               String path = sysMenu.getUrl().replace("/html/","").replace("/" + ss[ss.length - 1], "").replace("/", ":");
               String[] permStr = sysMenu.getPerms().split(",");
               Example example = new Example(Menu.class);
               example.createCriteria()
                               .andEqualTo("parentId", sysMenu.getMenuId())
                               .andEqualTo("type",Constant.MenuType.BUTTON.getValue());
               List<Menu> list = sysMenuService.selectListByExample(example);
               Set<String> set = new HashSet<>();
               List<Menu> updateList =  list.stream().filter(menu -> {
                   String perm = menu.getPerms().split(":")[menu.getPerms().split(":").length - 1];
                    for (String s: permStr ) {
                        if(perm.equals(s)){
                            set.add(s);
                            menu.setPerms(path + ":" + perm);
                            return true;
                        }
                    }
                   return false;
                } ).collect(Collectors.toList());
               List<Menu> deletList =  list.stream().filter(menu -> {
                   String perm = menu.getPerms().split(":")[menu.getPerms().split(":").length - 1];
                   for (String s: permStr ) {
                       if(perm.equals(s)){
                           return false;
                       }
                   }
                   return true;
               } ).collect(Collectors.toList());
               deletList.forEach(menu -> sysMenuService.deleteByEntity(menu));
               updateList.forEach(menu ->sysMenuService.update(menu) );
               Arrays.stream(permStr).forEach(s ->{
                   if(!set.contains(s)){
                       Menu childSysMenu = new Menu();
                       childSysMenu.setStatus(1);
                       childSysMenu.setCreateTime(new Date());
                       childSysMenu.setParentId(sysMenu.getMenuId());
                       childSysMenu.setType(Constant.MenuType.BUTTON.getValue());
                       childSysMenu.setOrderNum(0);
                       childSysMenu.setPerms(path + ":"+s);
                       switch (s){
                         case "search":
                           childSysMenu.setName("查找");
                           break;
                           case "save":
                               childSysMenu.setName("新增与修改");
                               break;
                           case "updateStatus":
                               childSysMenu.setName("审核");
                               break;
                           case "delete":
                               childSysMenu.setName("删除");
                               break;
                           case "import":
                               childSysMenu.setName("导入");
                               break;
                         case "sync":
                           childSysMenu.setName("同步");
                           break;
                           case "export":
                               childSysMenu.setName("导出");
                               break;
                           default:
                               break;
                       }
                       sysMenuService.insert(childSysMenu);
                   }
               } );
           }
        }
        return R.ok();
    }

    @RequestMapping("/get/{id}")
    public R get(@PathVariable("id") long id) {
        Menu sysMenu = sysMenuService.selectByKey(id);
        return R.ok().put("data", sysMenu);
    }

    @RequestMapping("/updateStatus")
    public R updateStatus(
            @Valid @Min(value = 0, message = "用户id必须大于0") long menuId,
            @RequestParam("status") int status) {
        Menu sysMenu = sysMenuService.selectByKey(menuId);
        if (sysMenu != null) {
            sysMenu.setStatus(status);
            sysMenuService.update(sysMenu);
            return R.ok();
        } else {
            return R.error("用户不存在");
        }
    }

}
